<?php


namespace app\admin\controller;

use app\admin\model\SystemAdmin;
use app\admin\model\SystemAuth;
use app\admin\model\SystemNode;
use app\common\controller\AdminController;
use app\admin\model\SystemLog;
use think\App;

/**
 * @ControllerAnnotation(title="系统管理")
 */
class System extends AdminController
{
    public ?SystemAdmin $admin_model = null;
    public ?SystemAuth $auth_model = null;
    public ?SystemNode $node_model = null;
    public ?SystemLog $log_model = null;

    public function __construct(App $app)
    {
        $this->admin_model = new SystemAdmin();
        $this->auth_model = new SystemAuth();
        $this->node_model = new SystemNode();
        $this->log_model = new SystemLog();
        parent::__construct($app);
    }

    /**
     * @NodeAnotation(title="管理员列表")
     */
    public function adminList()
    {
        $username = input('username','', 'trim');
        $page = input('page', 1, 'int');
        $pageSize = input('pageSize', 20, 'int');
        $ids = input('ids', '', 'trim');
        $export = input('export', 0, 'int');

        $where = [];
        $where[] = ['id', '<>', config('admin.super_admin_id')];
        if ($username) {
            $where[] = ['username', '=', $username];
        }
        if ($ids) {
            $where[] = ['id', 'IN', explode(',', $ids)];
        }
        //角色列表
        $authList = $this->auth_model->field('id,title')->where('status',1)->select()->toArray();
        $total = $this->admin_model->where($where)->value('count(1)');
        $list = [];
        if ($total > 0) {
            $list = $this->admin_model->field('id,auth_ids,username,nickname,login_num,status')->where($where)->page($page, $pageSize)->select()->toArray();
            $_authList = array_format_key($authList, 'id');
            foreach ($list as $key => $val) {
                $list[$key]['status_name'] = $val['status'] ? '开启' : '关闭';
                $auth_ids = $val['auth_ids'] ? explode(',', $val['auth_ids']) : [];
                $ret = array_map(function ($id) use ($_authList) {return $_authList[$id]??[];}, $auth_ids);
                $list[$key]['authTitle'] = array_filter($ret);
                $list[$key]['role_name'] = implode(',', array_column($list[$key]['authTitle'], 'title'));
            }
        }

        //导出
        if ($export) {
            $url = generateExcelFile($list, [
                'username'=> '登录账户',
                'nickname'=> '昵称',
                'role_name'=> '角色',
                'login_num'=> '登录次数',
                'status_name'=> '状态',
                'create_at'=> '添加时间',
            ]);
            $this->success(['url'=> $url]);
        }

        $res = [
            'total'=> $total,
            'list'=> $list,
            'authList'=> $authList,
        ];
        $this->success($res);
    }

    /**
     * @NodeAnotation(title="添加编辑管理员")
     */
    public function adminEdit()
    {
        $id = input('id', 0, 'int');
        $username = input('username', '', 'trim');
        $nickname = input('nickname', '', 'trim');
        $password = input('password', '', 'trim');
        $auth_ids = input('auth_ids',[]);
        $auth_ids = $auth_ids && is_array($auth_ids) ? implode(',', $auth_ids) : '';
        // 验证
        $this->validate([
            'username' => $username,
            'password' => $password,
        ],[
            'username' => 'require',
            'password' => empty($id) ? 'require' : '', // 新增时密码必填，编辑时可以不填
        ]);

        if ($id) {
            $update = [
                'auth_ids'=> $auth_ids,
                'nickname'=> $nickname,
            ];
            $password && $update['password'] = password($password);
            $this->admin_model->where(['id'=> $id])->update($update);
        } else {
            if ($this->admin_model->where(['username'=> $username])->value('id')) {
                $this->error('管理员已存在');
            }
            $insert = [
                'auth_ids'=> $auth_ids,
                'username'=> $username,
                'nickname'=> $nickname,
                'password'=> password($password),
            ];
            $this->admin_model->save($insert);
        }
        $this->success([],'保存成功');
    }

    /**
     * @NodeAnotation(title="删除管理员")
     */
    public function adminDel()
    {
        $id = input('id', 0, 'int');
        if (empty($id)) {
            $this->error('参数缺失');
        }
        if ($id == config('admin.super_admin_id')) {
            $this->error('超级管理员状态不允许修改');
        }
        $this->admin_model->where(['id'=> $id])->delete();
        $this->success([], '删除成功');
    }

    /**
     * @NodeAnotation(title="设置管理员状态")
     */
    public function adminEditStatus()
    {
        $id = input('id', '', 'trim');
        $status = input('status') ? 1 : 0;
        if (empty($id)) {
            $this->error('参数缺失');
        }
        $ids = explode(',', $id);
        $update = ['status'=> $status];
        foreach ($ids as $id) {
            if ($id == config('admin.super_admin_id')) {
                continue;
            }
            $this->admin_model->where(['id'=> $id])->update($update);
        }

        $this->success([], '设置成功');
    }

    /**
     * @NodeAnotation(title="角色列表")
     */
    public function authList()
    {
        $title = input('title','', 'trim');
        $page = input('page', 1, 'int');
        $pageSize = input('pageSize', 20, 'int');
        $ids = input('ids', '', 'trim');
        $export = input('export', 0, 'int');

        $where = [];
        if ($title) {
            $where[] = ['title', '=', $title];
        }
        if ($ids) {
            $where[] = ['id', 'IN', explode(',', $ids)];
        }
        $total = $this->auth_model->where($where)->value('count(1)');
        $list = [];
        if ($total > 0) {
            $list = $this->auth_model->field('id,title,status,remark,node_list,create_at')->where($where)->page($page, $pageSize)->select()->toArray();
            foreach ($list as $key => $val) {
                $list[$key]['status_name'] = $val['status'] ? '开启' : '关闭';
            }
        }
        //角色列表
        $authList = $this->auth_model->field('id,title')->where('status',1)->select()->toArray();

        //导出
        if ($export) {
            $url = generateExcelFile($list, [
                'id'=> 'ID',
                'title'=> '角色名称',
                'remark'=> '备注',
                'status_name'=> '状态',
                'create_at'=> '添加时间',
            ]);
            $this->success(['url'=> $url]);
        }

        $res = [
            'total'=> $total,
            'list'=> $list,
            'authList'=> $authList,
        ];
        $this->success($res);
    }

    /**
     * @NodeAnotation(title="添加编辑角色")
     */
    public function authEdit()
    {
        $id = input('id', 0, 'int');
        $title = input('title', '', 'trim');
        $remark = input('remark', '', 'trim');
        // 验证
        $this->validate(['title' => $title],['title' => 'require']);
        if ($id) {
            $update = [
                'title'=> $title,
                'remark'=> $remark,
            ];
            $this->auth_model->where(['id'=> $id])->update($update);
        } else {
            $insert = [
                'title'=> $title,
                'remark'=> $remark,
            ];
            $this->auth_model->save($insert);
        }
        $this->success([], '保存成功');
    }

    /**
     * @NodeAnotation(title="删除角色")
     */
    public function authDel()
    {
        $id = input('id', 0, 'int');
        $this->validate(['id' => $id],['id' => 'require']);
        $this->auth_model->where(['id'=> $id])->delete();
        $this->success([], '删除成功');
    }

    /**
     * @NodeAnotation(title="设置角色状态")
     */
    public function setAuthStatus()
    {
        $id = input('id', 0, 'int');
        $status = input('status') ? 1 : 0;
        $this->validate(['id' => $id],['id' => 'require']);

        $row = $this->auth_model->find($id);
        empty($row) && $this->error('数据不存在');
        $this->auth_model->where(['id'=> $id])->update(['status'=> $status]);
        $this->success([], '保存成功');
    }

    /**
     * @NodeAnotation(title="节点树")
     */
    public function nodeTree()
    {
        $list = (new SystemNode())->buildNodeTree2();
        $this->success(['list'=> $list]);
    }

    /**
     * @NodeAnotation(title="角色授权")
     */
    public function authNode()
    {
        $id = input('id', 0, 'int');
        $node_list = input('node_list',[]);
        $node_list = $node_list && is_array($node_list) ? $node_list : [];
        $this->validate(['id' => $id],['id' => 'require']);

        if ($node_list) {
            $node_list = $this->node_model->where('id', 'IN', $node_list)->where('type', 2)->column('id');
        }

        $update = [
            'node_list'=> implode(',', $node_list),
        ];
        $this->auth_model->where(['id'=> $id])->update($update);
        $this->success([], '保存成功');
    }

    /**
     * @NodeAnotation(title="节点列表")
     */
    public function nodeList()
    {
        $list = (new SystemNode())->getNodeTreeList();
        $this->success(['list'=> $list]);
    }

    /**
     * @NodeAnotation(title="强制刷新节点")
     */
    public function refreshNode()
    {
        $model = new SystemNode();
        $nodeList = $model->getNodelist();
        empty($nodeList) && $this->error('暂无需要更新的系统节点');
        try {
            $formatNodeList = array_format_key($nodeList, 'node');
            $existNodeList = $model->field('id,node')->select();
            foreach ($existNodeList as $vo) {
                //存在更新，不存在删除
                if (isset($formatNodeList[$vo['node']])) {
                    $model->where('id', $vo['id'])->update([
                        'title' => $formatNodeList[$vo['node']]['title'],
                    ]);
                    unset($formatNodeList[$vo['node']]);
                } else {
                    $model->where('id', $vo['id'])->delete();
                }
            }
            //批量添加新加的节点
            $model->saveAll($formatNodeList);
        } catch (\Exception $e) {
            $this->error('节点更新失败');
        }
        $this->success([], '节点刷新成功');
    }

    /**
     * @NodeAnotation(title="系统日志")
     */
    public function systemLog() {
        $admin_name = input('admin_name','', 'trim');
        $url = input('url','', 'trim');
        $startDate = input('startDate', '', 'trim');
        $endDate = input('endDate', '', 'trim');
        $page = input('page', 1, 'int');
        $pageSize = input('pageSize', 20, 'int');

        $where = [];
        if ($admin_name) $where[] = ['admin_name', '=', $admin_name];
        if ($url) $where[] = ['url', '=', $url];
        if ($startDate) $where[] = ['create_at', '>=', date('Y-m-d H:i:s', strtotime($startDate))];
        if ($endDate) $where[] = ['create_at', '<', date('Y-m-d H:i:s', strtotime($endDate)+86400)];

        $list = [];
        $total = $this->log_model->where($where)->value('count(1)');
        if ($total > 0) {
            $list = $this->log_model->where($where)->page($page, $pageSize)->order('id', 'desc')->select()->toArray();
        }

        $res = [
            'total'=> $total,
            'list'=> $list,
        ];
        $this->success($res);
    }
}